package com.winsdom.service.customer.impl;

import com.winsdom.entity.customer.CustomerEnterpriseUpdateRequest;
import com.winsdom.entity.customer.ContactInfo;
import com.winsdom.mapper.customer.CustomerEnterpriseUpdateMapper;
import com.winsdom.service.customer.CustomerEnterpriseUpdateService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 企业客户信息更新服务实现类
 * 负责处理企业客户基本信息、地址信息、联系人信息及相关配置的更新操作
 * 所有更新操作在一个事务中执行，确保数据一致性
 */
@Service
public class CustomerEnterpriseUpdateServiceImpl implements CustomerEnterpriseUpdateService {
    private static final Logger log = LoggerFactory.getLogger(CustomerEnterpriseUpdateServiceImpl.class);

    @Resource
    private CustomerEnterpriseUpdateMapper customerEnterpriseUpdateMapper;

    /**
     * 更新企业客户基本信息
     * 包含客户主表信息、企业扩展信息、地址信息、营业执照图片及联系人信息的更新
     * @param request 企业客户更新请求对象
     * @return 包含更新结果的Map，包含status和message字段
     */
    @Override
    @Transactional
    public Map<String, Object> updateEnterpriseBasicInfo(CustomerEnterpriseUpdateRequest request) {
        Long customerId = request.getCustomerId();
        Map<String, Object> result = new HashMap<>();

        // 分步更新各类信息，确保事务一致性
        updateCustomerBaseInfo(customerId, request);
        updateCustomerEnterpriseInfo(customerId, request);
        updateCustomerAddresses(customerId, request, 1, "registration");
        updateCustomerAddresses(customerId, request, 2, "office");
        updateBusinessLicenseImage(customerId, request);
        handleContactInfos(customerId, request.getContactInfos());

        result.put("status", "success");
        result.put("message", "更新成功");
        return result;
    }

    /**
     * 更新客户主表基本信息
     * @param customerId 客户ID
     * @param request 企业客户更新请求对象
     */
    private void updateCustomerBaseInfo(Long customerId, CustomerEnterpriseUpdateRequest request) {
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("customerName", request.getCustomerName());
        params.put("mobilePhone", request.getMobilePhone());
        params.put("email", request.getEmail());
        customerEnterpriseUpdateMapper.updateCustomerBaseInfo(params);
        log.debug("更新客户基本信息，客户ID：{}", customerId);
    }

    /**
     * 更新企业客户扩展信息
     * @param customerId 客户ID
     * @param request 企业客户更新请求对象
     */
    private void updateCustomerEnterpriseInfo(Long customerId, CustomerEnterpriseUpdateRequest request) {
        Map<String, Object> params = new HashMap<>();
        params.put("customerId", customerId);
        params.put("registrationNumber", request.getUnifiedSocialCreditCode());
        params.put("enterpriseNature", request.getEnterpriseNature());
        params.put("businessNature", request.getBusinessNature());
        params.put("taxStatus", convertTaxStatus(request.getTaxIdentity()));
        params.put("keyInvestment", convertKeyInvestment(request.getKeyInvestmentCustomer()));
        params.put("bankName", request.getBankName());
        params.put("accountNumber", request.getBankAccount());
        params.put("registeredCapital", request.getRegisteredCapital());
        params.put("employeeCount", request.getNumberOfPeople());
        customerEnterpriseUpdateMapper.updateCustomerEnterpriseInfo(params);
        log.debug("更新企业扩展信息，客户ID：{}", customerId);
    }

    /**
     * 将纳税身份字符串转换为系统内部编码
     * @param taxIdentity 纳税身份字符串
     * @return 对应的系统内部编码
     */
    private Integer convertTaxStatus(String taxIdentity) {
        if ("Small-scale taxpayer".equals(taxIdentity)) return 1;
        if ("General taxpayer".equals(taxIdentity)) return 2;
        log.warn("未知纳税身份：{}，默认返回null", taxIdentity);
        return null;
    }

    /**
     * 将重点招商状态字符串转换为系统内部编码
     * @param keyInvestment 重点招商状态字符串
     * @return 对应的系统内部编码
     */
    private Integer convertKeyInvestment(String keyInvestment) {
        if ("Yes".equals(keyInvestment)) return 1;
        if ("No".equals(keyInvestment)) return 0;
        log.warn("未知重点招商状态：{}，默认返回null", keyInvestment);
        return null;
    }

    /**
     * 更新客户地址信息（注册地址或办公地址）
     * @param customerId 客户ID
     * @param request 企业客户更新请求对象
     * @param addressType 地址类型（1-注册地址，2-办公地址）
     * @param prefix 地址字段前缀（registration-注册地址，office-办公地址）
     */
    private void updateCustomerAddresses(Long customerId, CustomerEnterpriseUpdateRequest request, Integer addressType, String prefix) {
        try {
            // 使用反射获取地址信息字段
            Field areaField = CustomerEnterpriseUpdateRequest.class.getDeclaredField(prefix + "Area");
            Field areaCodeField = CustomerEnterpriseUpdateRequest.class.getDeclaredField(prefix + "AreaCode");
            Field detailedAddressField = CustomerEnterpriseUpdateRequest.class.getDeclaredField(prefix + "DetailedAddress");

            areaField.setAccessible(true);
            areaCodeField.setAccessible(true);
            detailedAddressField.setAccessible(true);

            // 获取地址信息
            String area = (String) areaField.get(request);
            String areaCode = (String) areaCodeField.get(request);
            String detailedAddress = (String) detailedAddressField.get(request);

            // 如果所有地址字段都为空，则不执行更新操作
            if (area == null && areaCode == null && detailedAddress == null) {
                log.debug("无{}地址信息需要更新，客户ID：{}", prefix, customerId);
                return;
            }

            // 查询地址ID，判断是更新还是插入
            Integer addressId = customerEnterpriseUpdateMapper.getAddressId(customerId, addressType);

            if (addressId != null) {
                // 更新现有地址
                Map<String, Object> params = new HashMap<>();
                params.put("id", addressId);
                params.put("area", area);
                params.put("areaCode", areaCode);
                params.put("detailedAddress", detailedAddress);
                customerEnterpriseUpdateMapper.updateCustomerAddress(params);
            } else {
                // 插入新地址
                Map<String, Object> params = new HashMap<>();
                params.put("customerId", customerId);
                params.put("addressType", addressType);
                params.put("area", area);
                params.put("areaCode", areaCode);
                params.put("detailedAddress", detailedAddress);
                customerEnterpriseUpdateMapper.insertCustomerAddress(params);
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error("地址字段映射错误，客户ID：{}，错误：{}", customerId, e.getMessage());
            throw new RuntimeException("地址更新失败", e);
        }
    }

    /**
     * 更新营业执照图片信息
     * @param customerId 客户ID
     * @param request 企业客户更新请求对象
     */
    private void updateBusinessLicenseImage(Long customerId, CustomerEnterpriseUpdateRequest request) {
        String filePath = request.getBusinessLicenseImage();
        if (filePath == null) {
            log.debug("无营业执照图片需要更新，客户ID：{}", customerId);
            return;
        }

        // 查询证书ID，判断是更新还是插入
        Integer certificateId = customerEnterpriseUpdateMapper.getCertificateId(customerId);
        if (certificateId != null) {
            customerEnterpriseUpdateMapper.updateBusinessLicenseImage(customerId, filePath);
        } else {
            customerEnterpriseUpdateMapper.insertBusinessLicenseImage(customerId, filePath);
        }
    }

    /**
     * 处理联系人信息更新
     * @param customerId 客户ID
     * @param contactInfos 联系人信息列表
     */
    private void handleContactInfos(Long customerId, List<CustomerEnterpriseUpdateRequest.ContactInfo> contactInfos) {
        if (contactInfos == null || contactInfos.isEmpty()) {
            log.debug("无联系人信息需要更新，客户ID：{}", customerId);
            return;
        }

        // 获取客户现有联系人信息
        Map<String, Map<String, Object>> existingContactIds = customerEnterpriseUpdateMapper.getContactIdsByCustomerId(customerId);
        log.debug("客户ID {} 的现有联系人ID映射：{}", customerId, existingContactIds);

        for (CustomerEnterpriseUpdateRequest.ContactInfo contact : contactInfos) {
            String contactName = contact.getContactName();
            Map<String, Object> contactMap = existingContactIds.get(contactName);

            if (contactMap == null) {
                log.warn("联系人 {} 不存在，跳过更新", contactName);
                continue;
            }

            // 获取联系人ID并更新基本信息
            Long contactId = (Long) contactMap.get("id");
            if (contactId == null) {
                log.error("联系人 {} 的ID为空，跳过更新", contactName);
                continue;
            }

            // 更新联系人基本信息
            customerEnterpriseUpdateMapper.updateContactInfo(
                    contactId,
                    contact.getContactMobile(),
                    contact.getContactEmail()
            );
            log.debug("更新联系人 {} (ID: {}) 的联系方式", contactName, contactId);

            // 处理联系人与楼盘的关联关系
            List<String> propertyNames = contact.getReceiveProperties();
            // 先删除原有关联
            customerEnterpriseUpdateMapper.deleteContactProperties(contactId);
            if (propertyNames != null && !propertyNames.isEmpty()) {
                // 查询楼盘ID并建立新关联
                List<Integer> propertyIds = customerEnterpriseUpdateMapper.getPropertyIdsByNames(propertyNames);
                if (!propertyIds.isEmpty()) {
                    propertyIds.forEach(propertyId -> {
                        customerEnterpriseUpdateMapper.insertContactProperty(contactId, propertyId);
                        log.debug("为联系人 {} 关联楼盘ID {}", contactName, propertyId);
                    });
                } else {
                    log.warn("未找到楼盘名称 {} 对应的ID，跳过关联", propertyNames);
                }
            } else {
                log.debug("清空联系人 {} 的楼盘关联", contactName);
            }
        }
    }

    /**
     * 获取企业客户基本信息
     * @param customerId 客户ID
     * @return 包含企业客户基本信息的Map
     */
    public Map<String, Object> getEnterpriseBasicInfo(Long customerId) {
        List<Map<String, Object>> resultList = customerEnterpriseUpdateMapper.selectEnterpriseBasicInfo(customerId);
        Map<String, Object> result = new HashMap<>();

        log.info("查询结果列表大小: {}", resultList.size());
        System.out.println("DEBUG: 查询结果列表大小: " + resultList.size());  // 添加调试输出

        if (resultList.isEmpty()) {
            log.warn("未找到客户ID {} 的信息", customerId);
            return result;
        }

        // 打印原始查询结果用于调试
        log.info("原始查询结果: {}", resultList);
        System.out.println("DEBUG: 原始查询结果: " + resultList);

        // 提取企业基本信息（从第一条记录获取）
        Map<String, Object> baseInfo = resultList.get(0);
        result.put("customerId", baseInfo.get("customer_id"));
        result.put("customerType", baseInfo.get("customer_type"));
        result.put("customerName", baseInfo.get("customer_name"));
        result.put("mobilePhone", baseInfo.get("mobile_phone"));
        result.put("unifiedSocialCreditCode", baseInfo.get("unified_social_credit_code"));
        result.put("enterpriseNature", baseInfo.get("enterprise_nature"));
        result.put("businessNature", baseInfo.get("business_nature"));
        result.put("email", baseInfo.get("email"));
        result.put("taxIdentity", baseInfo.get("tax_identity"));
        result.put("keyInvestmentCustomer", baseInfo.get("key_investment_customer"));
        result.put("bankName", baseInfo.get("bank_name"));
        result.put("bankAccount", baseInfo.get("bank_account"));
        result.put("registeredCapital", baseInfo.get("registered_capital"));
        result.put("numberOfPeople", baseInfo.get("number_of_people"));
        result.put("businessLicenseImage", baseInfo.get("business_license_image"));
        result.put("registrationArea", baseInfo.get("registration_area"));
        result.put("registrationAreaCode", baseInfo.get("registration_area_code"));
        result.put("registrationDetailedAddress", baseInfo.get("registration_detailed_address"));
        result.put("officeArea", baseInfo.get("office_area"));
        result.put("officeAreaCode", baseInfo.get("office_area_code"));
        result.put("officeDetailedAddress", baseInfo.get("office_detailed_address"));

        // 处理联系人信息（从所有记录中提取并去重）
        List<ContactInfo> contactInfos = resultList.stream()
                .map(row -> {
                    ContactInfo ci = new ContactInfo();
                    ci.setContactId((Long) row.get("contact_id"));
                    ci.setContactName((String) row.get("contact_name"));
                    ci.setContactMobile((String) row.get("contact_mobile"));
                    ci.setContactEmail((String) row.get("contact_email"));

                    // 处理联系人关联的楼盘信息（从字符串解析为列表）
                    String propertyNames = (String) row.get("receive_property_names");
                    log.info("联系人 {} 的楼盘名称: {}", ci.getContactName(), propertyNames);
                    System.out.println("DEBUG: 联系人 " + ci.getContactName() + " 的楼盘名称: " + propertyNames);

                    ci.setReceiveProperties(StringUtils.isNotEmpty(propertyNames)
                            ? Arrays.asList(propertyNames.split(","))
                            : Collections.emptyList());

                    return ci;
                })
                .collect(Collectors.toList());

        result.put("contactInfos", contactInfos);
        log.info("最终返回结果: {}", result);
        System.out.println("DEBUG: 最终返回结果: " + result);

        return result;
    }
}